home *** CD-ROM | disk | FTP | other *** search
- (define-module (lang elisp primitives match)
- #:use-module (lang elisp internals fset)
- #:use-module (ice-9 regex)
- #:use-module (ice-9 optargs))
-
- (define last-match #f)
-
- (fset 'string-match
- (lambda (regexp string . start)
-
- (define emacs-string-match
-
- (if (defined? 'make-emacs-regexp)
-
- ;; This is what we would do if we had an
- ;; Emacs-compatible regexp primitive, here called
- ;; `make-emacs-regexp'.
- (lambda (pattern str . args)
- (let ((rx (make-emacs-regexp pattern))
- (start (if (pair? args) (car args) 0)))
- (regexp-exec rx str start)))
-
- ;; But we don't have Emacs-compatible regexps, and I
- ;; don't think it's worthwhile at this stage to write
- ;; generic regexp conversion code. So work around the
- ;; discrepancies between Guile/libc and Emacs regexps by
- ;; substituting the regexps that actually occur in the
- ;; elisp code that we want to read.
- (lambda (pattern str . args)
- (let loop ((discrepancies '(("^[0-9]+\\.\\([0-9]+\\)" .
- "^[0-9]+\\.([0-9]+)"))))
- (or (null? discrepancies)
- (if (string=? pattern (caar discrepancies))
- (set! pattern (cdar discrepancies))
- (loop (cdr discrepancies)))))
- (apply string-match pattern str args))))
-
- (let ((match (apply emacs-string-match regexp string start)))
- (set! last-match
- (if match
- (apply append!
- (map (lambda (n)
- (list (match:start match n)
- (match:end match n)))
- (iota (match:count match))))
- #f)))
-
- (if last-match (car last-match) %nil)))
-
- (fset 'match-beginning
- (lambda (subexp)
- (list-ref last-match (* 2 subexp))))
-
- (fset 'match-end
- (lambda (subexp)
- (list-ref last-match (+ (* 2 subexp) 1))))
-
- (fset 'substring substring)
-
- (fset 'match-data
- (lambda* (#:optional integers reuse)
- last-match))
-
- (fset 'set-match-data
- (lambda (list)
- (set! last-match list)))
-
- (fset 'store-match-data 'set-match-data)
-